home *** CD-ROM | disk | FTP | other *** search
- /*
- ** AIFF DataType
- **
- ** Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
- ** Public domain
- **
- ** :ts=4
- */
-
- #include "Data.h"
-
- // Mandatory library routines
-
- struct ClassBase * __asm __saveds LibInit(register __a0 BPTR LibSegment,register __d0 struct ClassBase *ClassBase,register __a6 struct ExecBase *ExecBase);
- struct ClassBase * __asm __saveds LibOpen(register __a6 struct ClassBase *Base);
- BPTR __asm __saveds LibExpunge(register __a6 struct ClassBase *Base);
- BPTR __asm __saveds LibClose(register __a6 struct ClassBase *Base);
- LONG __asm __saveds LibNull(register __a6 struct ClassBase *Base);
-
- // The only user-callable routine
-
- Class * __asm __saveds GetClassEngine(register __a6 struct ClassBase *ClassBase);
-
- // Library header data, defined in "RomTag.asm"
-
- extern UWORD __far LibVersion,
- LibRevision;
- extern UBYTE __far LibName[],
- LibID[];
-
- // Vector initialization table
-
- APTR LibVectors[] =
- {
- LibOpen,
- LibClose,
- LibExpunge,
- LibNull,
-
- GetClassEngine,
-
- (APTR)-1
- };
-
- // Library initialization table for MakeLibrary()
-
- struct { ULONG DataSize; APTR Table; APTR Data; struct ClassBase * (*Init)(); } __aligned LibInitTab =
- {
- sizeof(struct ClassBase),
- LibVectors,
- NULL,
- LibInit
- };
-
- /* AsyncStreamHandler():
- *
- * A special stream handler for use with iffparse.library and the
- * asyncio routines.
- */
-
- STATIC LONG __saveds __asm
- AsyncStreamHandler(register __a0 struct Hook *Hook,register __a2 struct IFFHandle *Handle,register __a1 struct IFFStreamCmd *ActionPkt)
- {
- struct AsyncFile *Stream = (struct AsyncFile *)Handle -> iff_Stream;
- LONG Bytes = ActionPkt -> sc_NBytes;
-
- switch(ActionPkt -> sc_Command)
- {
- case IFFCMD_READ:
-
- return(ReadAsync(Stream,ActionPkt -> sc_Buf,Bytes) != Bytes);
-
- case IFFCMD_WRITE:
-
- return(WriteAsync(Stream,ActionPkt -> sc_Buf,Bytes) != Bytes);
-
- case IFFCMD_SEEK:
-
- return(SeekAsync(Stream,Bytes,MODE_CURRENT) == -1);
-
- default:
-
- return(0);
- }
- }
-
- /* LibInit():
- *
- * Initialize the library.
- */
-
- struct ClassBase * __asm __saveds
- LibInit(register __a0 BPTR LibSegment,register __d0 struct ClassBase *ClassBase,register __a6 struct ExecBase *ExecBase)
- {
- // Set up the header data
-
- ClassBase -> LibNode . lib_Node . ln_Type = NT_LIBRARY;
- ClassBase -> LibNode . lib_Node . ln_Name = LibName;
- ClassBase -> LibNode . lib_Flags = LIBF_CHANGED | LIBF_SUMUSED;
- ClassBase -> LibNode . lib_Version = LibVersion;
- ClassBase -> LibNode . lib_Revision = LibRevision;
- ClassBase -> LibNode . lib_IdString = LibID;
-
- // Remember the segment pointer
-
- Segment = LibSegment;
-
- // Remember the exec library base pointer
-
- SysBase = ExecBase;
-
- // Initialize the shared data access semaphore
-
- InitSemaphore(&LockSemaphore);
-
- // Now take care of the IFFHandle I/O hook.
-
- AsyncHook . h_Entry = (HOOKFUNC)AsyncStreamHandler;
-
- return(ClassBase);
- }
-
- /* LibOpen(register __a6 struct ClassBase *ClassBase):
- *
- * Open the library, as called via OpenLibrary()
- */
-
- struct ClassBase * __asm __saveds
- LibOpen(register __a6 struct ClassBase *ClassBase)
- {
- // Increment usage count
-
- ClassBase -> LibNode . lib_OpenCnt++;
-
- // Prevent delayed expunge
-
- ClassBase -> LibNode . lib_Flags &= ~LIBF_DELEXP;
-
- // Is this the first initialization?
-
- if(ClassBase -> LibNode . lib_OpenCnt == 1)
- {
- // We are going to modify data while in multitasking,
- // so watch out
-
- ObtainSemaphore(&LockSemaphore);
-
- // Open libraries & classes
-
- if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",39))
- {
- if(IntuitionBase = OpenLibrary("intuition.library",39))
- {
- if(UtilityBase = OpenLibrary("utility.library",39))
- {
- if(IFFParseBase = OpenLibrary("iffparse.library",39))
- {
- if(DataTypesBase = OpenLibrary("datatypes.library",39))
- {
- if(SuperClassBase = OpenLibrary("datatypes/sound.datatype",39))
- {
- // Create a new class
-
- if(SoundClass = MakeClass(ClassBase -> LibNode . lib_Node . ln_Name,SOUNDDTCLASS,NULL,NULL,NULL))
- {
- extern Object * __saveds __asm ClassDispatch(register __a0 Class *class,register __a2 Object *object,register __a1 Msg msg);
-
- // Link the class dispatcher into it
- // and keep a pointer to the library
- // base
-
- SoundClass -> cl_Dispatcher . h_Entry = (HOOKFUNC)ClassDispatch;
- SoundClass -> cl_UserData = (ULONG)ClassBase;
-
- // Make the class publicly available
-
- AddClass(SoundClass);
-
- // Release the lock
-
- ReleaseSemaphore(&LockSemaphore);
-
- // Return the library base pointer
-
- return(ClassBase);
- }
-
- // Clean up...
-
- CloseLibrary(SuperClassBase);
-
- SuperClassBase = NULL;
- }
-
- CloseLibrary(DataTypesBase);
-
- DataTypesBase = NULL;
- }
-
- CloseLibrary(IFFParseBase);
-
- IFFParseBase = NULL;
- }
-
- CloseLibrary(UtilityBase);
-
- UtilityBase = NULL;
- }
-
- CloseLibrary(IntuitionBase);
-
- IntuitionBase = NULL;
- }
-
- CloseLibrary(DOSBase);
-
- DOSBase = NULL;
- }
-
- // Release the lock
-
- ReleaseSemaphore(&LockSemaphore);
-
- // No success
-
- return(NULL);
- }
- else
- return(ClassBase);
- }
-
- /* LibExpunge(register __a6 struct ClassBase *ClassBase):
- *
- * Expunge the library, remove it from memory
- */
-
- BPTR __asm __saveds
- LibExpunge(register __a6 struct ClassBase *ClassBase)
- {
- // No more callers have the library open?
-
- if(!ClassBase -> LibNode . lib_OpenCnt && Segment)
- {
- // Remember the segment pointer, so it can be unloaded
-
- BPTR TempSegment = Segment;
-
- // Remove the library from the public list
-
- Remove(ClassBase);
-
- // Free the vector table and the library data
-
- FreeMem((BYTE *)ClassBase - ClassBase -> LibNode . lib_NegSize,ClassBase -> LibNode . lib_NegSize + ClassBase -> LibNode . lib_PosSize);
-
- // Return the segment pointer
-
- return(TempSegment);
- }
- else
- {
- // Expunge it later
-
- ClassBase -> LibNode . lib_Flags |= LIBF_DELEXP;
-
- // Can't close yet...
-
- return(NULL);
- }
- }
-
- /* LibClose(register __a6 struct ClassBase *ClassBase):
- *
- * Close the library, as called by CloseLibrary()
- */
-
- BPTR __asm __saveds
- LibClose(register __a6 struct ClassBase *ClassBase)
- {
- // Decrement usage count
-
- if(ClassBase -> LibNode . lib_OpenCnt)
- ClassBase -> LibNode . lib_OpenCnt--;
-
- // No more users?
-
- if(!ClassBase -> LibNode . lib_OpenCnt && SysBase)
- {
- // We are going to modify shared data,
- // so watch out
-
- ObtainSemaphore(&LockSemaphore);
-
- // Clean up...
-
- if(SoundClass)
- {
- RemoveClass(SoundClass);
-
- FreeClass(SoundClass);
-
- SoundClass = NULL;
- }
-
- if(SuperClassBase)
- {
- CloseLibrary(SuperClassBase);
-
- SuperClassBase = NULL;
- }
-
- if(DataTypesBase)
- {
- CloseLibrary(DataTypesBase);
-
- DataTypesBase = NULL;
- }
-
- if(UtilityBase)
- {
- CloseLibrary(UtilityBase);
-
- UtilityBase = NULL;
- }
-
- if(IFFParseBase)
- {
- CloseLibrary(IFFParseBase);
-
- IFFParseBase = NULL;
- }
-
- if(IntuitionBase)
- {
- CloseLibrary(IntuitionBase);
-
- IntuitionBase = NULL;
- }
-
- if(DOSBase)
- {
- CloseLibrary(DOSBase);
-
- DOSBase = NULL;
- }
-
- // Release the lock
-
- ReleaseSemaphore(&LockSemaphore);
-
- // Can we remove ourselves?
-
- if(ClassBase -> LibNode . lib_Flags & LIBF_DELEXP)
- return(LibExpunge(ClassBase));
- }
-
- return(NULL);
- }
-
- /* LibNull(register __a6 struct ClassBase *ClassBase):
- *
- * Mandatory dummy function
- */
-
- LONG __asm __saveds
- LibNull(register __a6 struct ClassBase *ClassBase)
- {
- return(NULL);
- }
-
- /* GetClassEngine(register __a6 struct ClassBase *ClassBase):
- *
- * Get access to the class this library implements.
- */
-
- Class * __asm __saveds
- GetClassEngine(register __a6 struct ClassBase *ClassBase)
- {
- Class *class;
-
- // Access shared data
-
- ObtainSemaphore(&LockSemaphore);
-
- // Remember the class pointer
-
- class = SoundClass;
-
- // Release the lock
-
- ReleaseSemaphore(&LockSemaphore);
-
- // Return the pointer
-
- return(class);
- }
-